package com.example.prison.controller;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.example.prison.config.ApiUtil;
import com.example.prison.config.Response;
import com.example.prison.entity.*;
import com.example.prison.entity.vo.DefenceAreaVO;
import com.example.prison.service.*;
import com.example.prison.util.APIUtil;
import com.example.prison.webSocket.WsServerEndpoint;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.example.prison.config.ApiUtil.hourProcess;
import static com.example.prison.config.ApiUtil.minProcess;
import static com.example.prison.util.APIUtil.setCloseArea;
import static com.example.prison.util.APIUtil.setErrorArea;
import static com.example.prison.webSocket.WsServerEndpoint.sessionMap;

@Slf4j
@Api("防区管理")
@RestController
@RequestMapping("/api")
public class AreaManagementController {

    @Autowired
    private AreaManagementService areaManagementService;

    @Autowired
    private AreaRecordService areaRecordService;

    @Autowired
    private AlarmManagementService alarmManagementService;

    @Autowired
    private AlarmRecordService alarmRecordService;

    @Autowired
    private SystemInfoService systemInfoService;

    @Autowired
    private SystemLogService systemLogService;

    @Autowired
    private HistoricalAlarmDataService historicalAlarmDataService;


    Map<String, AreaManagement> map = new HashMap<>();

    @ApiOperation("获取防区实时状态")
    @GetMapping("/getAreaRealtimeState")
    public Response<PageInfo<AreaManagement>> getAreaRealtimeState(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                      @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) throws IOException {
        log.info("获取防区实时状态");
        List<AreaManagement> list = areaManagementService.list();
        List<DefenceAreaVO> defenceList = new ArrayList<>();

//        if(ObjectUtils.isEmpty(map)) {
//            PageInfo<AreaManagement> pageInfo = areaManagementService.get(pageNumber, pageSize);
//            List<AreaManagement> oldListData = pageInfo.getList();
//            for (AreaManagement area : oldListData) {
//                map.put(area.getDefenseSection(), area);
//            }
//        }

        for (AreaManagement area : list) {
            //alarmStatus换为对应文字
            area.setAlarmStatus(APIUtil.getAlarmStatus(area.getAlarmStatus()));
            AreaManagement data = area;
            log.info("防区"+data.getDefenseSection()+"模块地址："+data.getModuleAddress()+"旧状态：U1:"+data.getVoltage1()+",1状态:"+data.getStatus1()
                    +",U2:"+data.getVoltage2() +",2状态:"+data.getStatus2()+",报警等级:"+data.getAlarmLevel()+",警情状态:"+data.getAlarmStatus() );
//            log.info("开始查询防区"+area.getDefenseSection()+"的实时状态, "+area);
            if(ObjectUtils.isEmpty(area.getGatewayAddress()) || ObjectUtils.isEmpty(area.getGatewayPort())
            || ObjectUtils.isEmpty(area.getModuleAddress()) ) {
                area = setErrorArea(area);
                area.setAlarmLevel("未设置模块地址");
            }
            else {
                //内网查询数值塞入
                byte[] message = new byte[]{0x03, 0x00, 0x01, 0x00, 0x08};
////        String result = getStatusMessage("192.168.3.140", 8886, moduleAddress, message);
//            String result = getStatusMessage("10.10.10.113", 8886, moduleAddress, message);

                for(int i = 0; i < 3; i++) {
                    try {
                        Thread.sleep(200);
                    } catch (Exception e) {
                        System.out.println("程序减少网关压力休眠失败");
                    }
                    area.setAlarmLevel("正常");
                    area.setAlarmStatus("正常");
                    area = APIUtil.getSmallAreaStatusMessage(area, area.getGatewayAddress(), Integer.valueOf(area.getGatewayPort()),
                            Integer.valueOf(area.getModuleAddress()), message);
                    if( !(data.getVoltage1() == "--" || data.getVoltage2() == "--") ) {
                        i = 10;
                    }
                }
                log.info("成功获取防区" + area.getDefenseSection() + "实时状态：U1:"+area.getVoltage1()+",1状态:"+area.getStatus1()
                        +",U2:"+area.getVoltage2() +",2状态:"+area.getStatus2()+",报警等级:"+area.getAlarmLevel()+",警情状态:"+area.getAlarmStatus() );

                area.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                String statusAlarm = "";
                area.setAlarmStatus(APIUtil.getAlarmStatus(area.getStatus1()));
                if (!Objects.equals(area.getStatus1(), "1")) {
                    statusAlarm = APIUtil.getAlarmStatus(area.getStatus1());
                    area.setAlarmStatus(statusAlarm);
                }
                if (!Objects.equals(area.getStatus2(), "1")) {
                    statusAlarm = APIUtil.getAlarmStatus(area.getStatus2());
                    area.setAlarmStatus(statusAlarm);
                }

                if (area.getVoltage1() == "--" || area.getVoltage2() == "--") {

                } else {
                    //防区关闭时所有电压、电流均为0
                    if (area.getStatus() == 0) {
                        log.info("防区关闭时所有电压、电流均为0");
                        setCloseArea(area);
                    } else {

                        //获取三个电压警戒等级对应的电压百分比
                        if (!(area.getInVoltage().equals("--") || area.getInVoltage().equals("0")
                                || ObjectUtils.isEmpty(area.getInVoltage()))
                                && ObjectUtils.isNotEmpty(map.get(area.getDefenseSection()))) {
                            log.info("获取电压警戒等级数据");
                            String alarmOne = alarmManagementService.getOneLevel("一级").getVoltage();
                            String alarmTwo = alarmManagementService.getOneLevel("二级").getVoltage();
                            String alarmThree = alarmManagementService.getOneLevel("三级").getVoltage();

                            //AreaManagement data = map.get(area.getDefenseSection());
                            if (!(data.getVoltage1() == "--" || data.getVoltage2() == "--")) {
                                log.info("计算电压警戒等级");
                                if (Objects.equals(area.getStatus1(), "1")) {
                                    String level = APIUtil.CountAlarmLevel(area.getVoltage1(), data.getVoltage1(), alarmOne, alarmTwo, alarmThree);
                                    area.setAlarmLevel(level);
                                }
                                if (Objects.equals(area.getStatus2(), "1") && area.getAlarmLevel() == "正常") {
                                    String level = APIUtil.CountAlarmLevel(area.getVoltage2(), data.getVoltage2(), alarmOne, alarmTwo, alarmThree);
                                    area.setAlarmLevel(level);
                                }
                            }
                        }
                    }
                }
                //alarmStatus换为对应文字
                area.setStatus1(APIUtil.getAlarmStatus(area.getStatus1()));
                area.setStatus2(APIUtil.getAlarmStatus(area.getStatus2()));
                area.setAlarmStatus(APIUtil.getAlarmStatus(area.getAlarmStatus()));
                //更新防区数据
                areaManagementService.updateAreaVol(area, area.getId());
                map.put(area.getDefenseSection(), area);

                //每隔一小时记录一次防区实时数据
                String lastTime = "0001-01-01 00:00:00";
                if(ObjectUtils.isNotEmpty(areaRecordService.getByDefenseSection(1,10, area.getDefenseSection()).getList())) {
                    lastTime = areaRecordService.getByDefenseSection(1,10, area.getDefenseSection()).getList().get(0).getTime();
                }
                String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                if (APIUtil.timeSubtraction(time, lastTime) > 3600) {
                    log.info("记录防区实时数据");
                    AreaRecord record = new AreaRecord();
                    BeanUtils.copyProperties(area, record);
                    record.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                    areaRecordService.add(record);
                }

                if (area.getStatus() == 1) {
                    if ((!area.getAlarmLevel().equals("正常") || !area.getAlarmStatus().equals("1"))) {
                        //开启防区时生成报警数据
                        log.info(area.getDefenseSection() + "防区电压异常，生成报警数据");
                        AlarmRecord alarmRecord = new AlarmRecord();
                        BeanUtils.copyProperties(area, alarmRecord);
                        alarmRecord.setNumber(area.getDefenseSection());
                        alarmRecord.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                        alarmRecord.setSolve("未处理");
//                alarmRecord.setDevice(area.getDeviceNumber());
                        if (!area.getAlarmStatus().equals("1")) {
                            alarmRecord.setLevel(APIUtil.getAlarmStatus(area.getAlarmStatus()));
                        } else if (!area.getAlarmLevel().equals("正常")) {
                            alarmRecord.setLevel(area.getAlarmLevel());
                        } else {
                            alarmRecord.setLevel(area.getAlarmLevel());
                        }
                        //Level换为对应文字
                        alarmRecord.setAlarmStatus(APIUtil.getAlarmStatus(alarmRecord.getLevel()));
                        int res = alarmRecordService.add(alarmRecord);
                        if (res == -1) {
                            log.info("已有该防区的对应未处理报警数据" );
                        }

                        //生成历史报警记录
                        HistoricalAlarmData historyAlarm = new HistoricalAlarmData();
                        BeanUtils.copyProperties(area, historyAlarm);
                        String newTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                        historyAlarm.setStartTime(newTime);
                        historyAlarm.setSolveStatus("未处理");
                        if (ObjectUtils.isNotEmpty(historicalAlarmDataService.getOneAlarmData(area.getDefenseSection(), area.getAlarmLevel(), area.getAlarmStatus()))) {
                            HistoricalAlarmData lastHHistoricalAlarm = historicalAlarmDataService.getOneAlarmData(area.getDefenseSection(), area.getAlarmLevel(), area.getAlarmStatus());
                            if (hourProcess(1).compareTo(lastHHistoricalAlarm.getStartTime()) < 0) {
                                //同中报警一小时之内不再新增
                                historicalAlarmDataService.add(historyAlarm);
                            }
                        } else {
                            historicalAlarmDataService.add(historyAlarm);
                        }

                    }
                }

//            DefenceAreaVO defence = new DefenceAreaVO();
//            DefenceArea defenceArea = defenceAreaService.getByName(area.getDefenseSection());
//            defence.setId(defenceArea.getId());
//            BeanUtils.copyProperties(area,defence);
//            defenceList.add(defence);
            }
        }

        PageInfo<AreaManagement> pageInfo = areaManagementService.get(pageNumber, pageSize);

        //建立webSocket，发送信息
        if(ObjectUtils.isNotEmpty(sessionMap)) {
            WsServerEndpoint.sendMessage(String.valueOf(pageInfo.getList()));
//            WsServerSocket.sendMessage(String.valueOf(defenceList));
        } else {
//            System.out.println(defenceList);
            log.info("无webSocket连接");
        }

        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("获取防区列表")
    @GetMapping("/getArea")
    public Response<PageInfo<AreaManagement>> getArea(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                        @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        log.info("获取防区列表");
//        systemLogService.add("获取防区列表");
        PageInfo<AreaManagement> pageInfo = areaManagementService.get(pageNumber, pageSize);
        List<AreaManagement> oldListData = pageInfo.getList();
        for (AreaManagement area : oldListData) {
            map.put(area.getDefenseSection(), area);
        }
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("获取防区及哨位列表")
    @GetMapping("/getAllArea")
    public Response<PageInfo<AreaManagement>> getAllArea(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                      @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        log.info("获取防区及哨位列表");
//        systemLogService.add("获取防区及哨位列表");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getAllArea(pageNumber, pageSize);
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("获取哨位列表")
    @GetMapping("/getSentryPostArea")
    public Response<PageInfo<AreaManagement>> getSentryPostArea(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                      @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        log.info("获取哨位列表");
//        systemLogService.add("获取哨位列表");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getSentryPostArea(pageNumber, pageSize);
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("新增防区")
    @PostMapping("/addArea")
    public Response<?> addArea(@RequestBody AreaManagement area) {
        log.info("新增防区");
        systemLogService.add("新增防区");
        int result = areaManagementService.add(area);
        if (result == -1) {
            return Response.error("防区已存在！");
        }
        if (result == -2) {
            return Response.error("系统信息不存在！");
        }
        if (result == -3) {
            return Response.error("模块地址未设置！");
        }
        return Response.success("添加成功！");
    }

    @ApiOperation("依据id删除防区")
    @PostMapping("/deleteArea")
    public Response<?> deleteAreaById(@Parameter(description = "防区ID") @RequestBody Integer[] ids) {
        log.info("依据id删除防区");
        systemLogService.add("依据id删除防区");
        int result = areaManagementService.delete(ids);
        if (result == -1) {
            return Response.error("防区不存在！");
        } else if (result == 0) {
            return Response.error("简略防区列表中该区域不存在！");
        }
        return Response.success("删除成功！");
    }

    @ApiOperation("依据防区段编号删除防区")
    @PostMapping("/deleteAreaBySection")
    public Response<?> deleteAreaBySection(@Parameter(description = "防区段编号") @RequestParam(value = "defenseSection") String defenseSection) {
        log.info("依据防区段编号删除防区");
        systemLogService.add("依据防区段编号删除防区");
        int result = areaManagementService.deleteBySection(defenseSection);
        if (result == -1) {
            return Response.error("防区不存在！");
        } else if (result == 0) {
            return Response.error("简略防区列表中该区域不存在！");
        }
        return Response.success("删除成功！");

    }

    @ApiOperation("编辑防区")
    @PostMapping("/updateArea")
    public Response<?> updateArea(@RequestBody AreaManagement area) {
        log.info("编辑防区");
        systemLogService.add("编辑防区");
        Integer id = area.getId();
        int result = areaManagementService.updateArea(area, id);
        if (result == -1) {
            return Response.error("更新失败！防区已存在！");
        } else if (result == 0) {
            return Response.error("简略防区列表中该区域不存在！");
        } else if (result == 2) {
            return Response.error("该防区不存在！");
        } else {
            return Response.success("更新成功！");
        }
    }

    @ApiOperation("依据id获取防区列表")
    @GetMapping("/getAreaById")
    public Response<AreaManagement> getAreaById(@Parameter(description = "防区ID")@RequestParam(value = "areaId") Integer areaId) {
        log.info("依据id获取防区列表");
        systemLogService.add("依据id获取防区列表");
        AreaManagement area = areaManagementService.getById(areaId);
        if(ObjectUtils.isEmpty(area)) {
            return Response.error("此防区id不存在！");
        }
        return Response.success("获取成功！", area);
    }

    @ApiOperation("依据防区段编号获取防区")
    @GetMapping("/getBySection")
    public Response<PageInfo<AreaManagement>> getBySection(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                      @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                                      @Parameter(description = "防区段编号")@RequestParam(value = "defenseSection") String defenseSection) {
        log.info("依据防区段编号获取防区");
//        systemLogService.add("依据防区段编号获取防区");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getBySection(pageNumber, pageSize, defenseSection);
        if(ObjectUtils.isEmpty(pageInfo.getList())) {
            return Response.error("此防区不存在！");
        }
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("依据防区段点位编号获取防区")
    @GetMapping("/getByPoint")
    public Response<PageInfo<AreaManagement>> getByPoint(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                           @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                                           @Parameter(description = "防区段点位编号")@RequestParam(value = "defenseSection") String defenseSectionPoint) {
        log.info("依据防区段点位编号获取防区");
//        systemLogService.add("依据防区段点位编号获取防区");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getByPoint(pageNumber, pageSize, defenseSectionPoint);
        if(ObjectUtils.isEmpty(pageInfo.getList())) {
            return Response.error("此防区不存在！");
        }
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("依据防区段编号和点位编号获取防区")
    @GetMapping("/getBySectionAndPoint")
    public Response<PageInfo<AreaManagement>> getBySectionAndPoint(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                                     @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                                                     @Parameter(description = "防区段编号")@RequestParam(value = "defenseSection") String defenseSection,
                                                                     @Parameter(description = "防区段点位编号")@RequestParam(value = "defenseSectionPoint") String defenseSectionPoint) {
        log.info("依据防区段编号和点位编号获取防区");
//        systemLogService.add("依据防区段编号和点位编号获取防区");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getBySectionAndPoint(pageNumber, pageSize, defenseSection, defenseSectionPoint);
        if(ObjectUtils.isEmpty(pageInfo.getList())) {
            return Response.error("此防区不存在！");
        }
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("依据哨卫编号获取哨卫防区")
    @GetMapping("/getBySentryPost")
    public Response<PageInfo<AreaManagement>> getBySentryPost(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                         @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                                         @Parameter(description = "哨卫编号")@RequestParam(value = "sentryPost") String sentryPost) {
        log.info("依据哨卫编号获取防区");
        systemLogService.add("依据哨卫编号获取防区");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getBySentryPost(pageNumber, pageSize, sentryPost);
        if(ObjectUtils.isEmpty(pageInfo.getList())) {
            return Response.error("此防区不存在！");
        }
        return Response.success("获取成功！", pageInfo);
    }

    @ApiOperation("依据警情状态获取防区")
    @GetMapping("/getAreaByAlarmStatus")
    public Response<PageInfo<AreaManagement>> getAreaByAlarmStatus(@RequestParam(value = "pageNumber", defaultValue = "1") int pageNumber,
                                                                  @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                                                  @Parameter(description = "警情状态")@RequestParam(value = "alarmStatus") String alarmStatus) {
        log.info("依据警情状态获取防区");
        systemLogService.add("依据警情状态获取防区");
        PageInfo<AreaManagement> pageInfo = areaManagementService.getByAlarmStatus(pageNumber, pageSize, alarmStatus);
        if(ObjectUtils.isEmpty(pageInfo.getList())) {
            return Response.error("此防区不存在！");
        }
        return Response.success("获取成功！", pageInfo);
    }

}
